package system

import (
	"context"
	"gf_blog_admin/internal/dao"
	"gf_blog_admin/internal/model"
	"gf_blog_admin/internal/service"
	"gf_blog_admin/utility/utils"
	"github.com/gogf/gf/v2/database/gdb"
	"github.com/gogf/gf/v2/errors/gerror"
)

type sSysDictData struct{}

func init() {
	service.RegisterSysDictData(NewSysDictData())
}

func NewSysDictData() *sSysDictData {
	return &sSysDictData{}
}

func (s *sSysDictData) List(ctx context.Context, in *model.DictDataListInput) (out []*model.DictDataItem, total int, err error) {
	var (
		cls = dao.BlSysDictItem.Columns()
		m   = dao.BlSysDictItem.Ctx(ctx)
	)

	if in.DictId != "" {
		m = m.Where(cls.DictId, utils.StrToInt(in.DictId))
	}
	if in.DictCode != "" {
		var (
			hasTable = dao.BlSysDict.Table()
			hasCls   = dao.BlSysDict.Columns()
		)
		m = m.InnerJoinOnFields(hasTable, hasCls.Id, "=", cls.DictId).
			WherePrefix(hasTable, hasCls.DictCode, in.DictCode)
	}

	out = make([]*model.DictDataItem, 0)
	err = m.OrderDesc(cls.ItemSort).OrderDesc(cls.Id).
		Fields(
			cls.Id, cls.ItemName, cls.ItemValue, cls.ItemRemark, cls.ItemSort, cls.ItemStatus, cls.DictId,
		).
		Page(in.Page, in.PageSize).
		ScanAndCount(&out, &total, false)
	return
}

func (s *sSysDictData) Detail(ctx context.Context, id uint64) (out *model.DictItem, err error) {
	cls := dao.BlSysDictItem.Columns()
	err = dao.BlSysDictItem.Ctx(ctx).Where(cls.Id, id).Scan(&out)
	if err != nil {
		return nil, err
	}
	if out == nil {
		return nil, gerror.New("记录不存在")
	}
	return
}

func (s *sSysDictData) Store(ctx context.Context, in *model.DictDataFormInput) (err error) {
	err = dao.BlSysDictItem.Transaction(ctx, func(ctx context.Context, tx gdb.TX) error {
		_, err = dao.BlSysDictItem.Ctx(ctx).Data(in).Insert()
		return err
	})
	return
}

func (s *sSysDictData) Update(ctx context.Context, id uint64, in *model.DictDataFormInput) (err error) {
	if _, err = s.Detail(ctx, id); err != nil {
		return err
	}

	err = dao.BlSysDictItem.Transaction(ctx, func(ctx context.Context, tx gdb.TX) error {
		cls := dao.BlSysDictItem.Columns()
		_, err = dao.BlSysDictItem.Ctx(ctx).Where(cls.Id, id).Data(in).Update()
		return err
	})
	return
}

func (s *sSysDictData) Destroy(ctx context.Context, ids []uint64) (err error) {
	var (
		check bool
		cls   = dao.BlSysDictItem.Columns()
		m     = dao.BlSysDictItem.Ctx(ctx)
	)

	ids = utils.UniqueIds(ids)
	if check, err = m.WhereIn(cls.Id, ids).Exist(); err != nil {
		return err
	} else if !check {
		return gerror.New("操作失败")
	}

	err = dao.BlSysDictItem.Transaction(ctx, func(ctx context.Context, tx gdb.TX) error {
		_, err = m.WhereIn(cls.Id, ids).Delete()
		return err
	})
	return
}
